/*
 * Copyright 2019 xiaomaoguai.com All right reserved. This software is the
 * confidential and proprietary information of xiaomaoguai.com ("Confidential
 * Information"). You shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the license agreement you entered
 * into with xiaomaoguai.com.
 */

package com.xiaomaoguai.core.next.web.common;

import java.io.IOException;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import com.google.common.collect.Maps;

/**
 * Application一些常用方法
 *
 * @author chenyao
 * @since 2018年11月13日 下午3:15:27
 * @see app.myoss.cloud.web.spring.boot.BootApplication
 */
public class SharkApplication {
    /**
     * 将字符串中的<code>#{user.home}</code>替换为用户的家目录
     *
     * @param input 待替换的字符串
     * @return 替换后的字符串
     */
    public static String replaceUserHome(String input) {
        return StringUtils.replace(input, "#{user.home}", System.getProperty("user.home"));
    }

    /**
     * 解析command line arguments的参数，转换为Map对象
     * <p>
     * Parses a {@code String[]} of command line arguments in order to populate
     * a {@link Map} object.
     * <h3>Working with option arguments</h3> Option arguments must adhere to
     * the exact syntax:
     *
     * <pre class="code">
     * --optName[=optValue]
     * </pre>
     *
     * That is, options must be prefixed with "{@code --}", and may or may not
     * specify a value. If a value is specified, the name and value must be
     * separated <em>without spaces</em> by an equals sign ("=").
     * <h4>Valid examples of option arguments</h4>
     *
     * <pre class="code">
     * --foo
     * --foo=bar
     * --foo="bar then baz"
     * --foo=bar,baz,biz
     * </pre>
     *
     * <h4>Invalid examples of option arguments</h4>
     *
     * <pre class="code">
     * -foo
     * --foo bar
     * --foo = bar
     * --foo=bar --foo=baz --foo=biz
     * </pre>
     *
     * <h3>Working with non-option arguments</h3> Any and all arguments
     * specified at the command line without the "{@code --}" option prefix will
     * be considered as "non-option arguments"
     *
     * @param args 参数列表，比如：--server.port=8080
     *            <p>
     *            --server.port=8080 --spring.redis.port=6379
     * @return 转换为Map对象
     */
    public static Map<String, String> simpleCommandLineArgsParser(String... args) {
        Map<String, String> multiMap = Maps.newHashMap();
        for (String arg : args) {
            if (arg.startsWith("--")) {
                String optionText = arg.substring(2, arg.length());
                String optionName;
                String optionValue = null;
                if (optionText.contains("=")) {
                    optionName = optionText.substring(0, optionText.indexOf('='));
                    optionValue = optionText.substring(optionText.indexOf('=') + 1, optionText.length());
                } else {
                    optionName = optionText;
                }
                if (optionName.isEmpty() || (optionValue != null && optionValue.isEmpty())) {
                    throw new IllegalArgumentException("Invalid argument syntax: " + arg);
                }
                multiMap.put(optionName, optionValue);
            }
        }
        return multiMap;
    }

    /**
     * 读取<code>xxx.properties</code>配置文件，使用
     * {@link PathMatchingResourcePatternResolver#getResource(String)}
     * 解析路径，支持通配符（比如：classpath:config.properties）
     *
     * @param configPropertiesPath 配置文件的路径
     * @return Properties
     * @throws IOException IOException
     */
    public static Properties loadPropertiesByPathMatch(String configPropertiesPath) throws IOException {
        PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
        Resource configLocation = pathMatchingResourcePatternResolver.getResource(configPropertiesPath);
        return PropertiesLoaderUtils.loadProperties(configLocation);
    }
}
